package com.yk.i_wms.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yk.i_wms.common.model.CheckWarehouseEnum;
import com.yk.i_wms.common.model.Result;
import com.yk.i_wms.dto.SmsCheckDocDTO;
import com.yk.i_wms.mapper.SmsCheckDocMapper;
import com.yk.i_wms.model.*;
import com.yk.i_wms.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 盘点单
 *
 * @author hbq
 * @date 2021-04-14 19:17:53
 */
@Slf4j
@Service
public class SmsCheckDocServiceImpl extends ServiceImpl<SmsCheckDocMapper, SmsCheckDoc> implements ISmsCheckDocService {
    @Resource
    private SmsCheckDocMapper smsCheckDocMapper;
    @Autowired
    private ISmsCheckDocDetailService smsCheckDocDetailService;
    @Autowired
    private ISmsCheckDocRecordService smsCheckDocRecordService;
    @Autowired
    private ISmsStockInfoService smsStockInfoService;
    @Autowired
    private IUmsUserService umsUserService;
    /**
     * 列表
     * @param params
     * @return
     */
    public Page<Map> findList(Map<String, Object> params){
        Integer pageNum = MapUtils.getInteger(params, "pageNum");
        Integer pageSize = MapUtils.getInteger(params, "pageSize");
        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = -1;
        }
        Page<Map> pages = new Page<>(pageNum, pageSize);
        return smsCheckDocMapper.findList(pages, params);
    }

    @Override
    public Result saveAll(SmsCheckDocDTO smsCheckDocDTO) {
        SmsCheckDoc smsCheckDoc=smsCheckDocDTO;
        if (smsCheckDoc.getDocState()!=1){
            return Result.failed("非新建状态不允许修改");
        }
        log.info("新建或更新盘点单：{}",smsCheckDocDTO);
        String docNo =StrUtil.isBlank(smsCheckDocDTO.getDocNo())?getNewNo():smsCheckDocDTO.getDocNo();
        smsCheckDoc.setDocNo(docNo);
        //删除原有docNo的详情
        smsCheckDocDetailService.remove(new LambdaQueryWrapper<SmsCheckDocDetail>().eq(SmsCheckDocDetail::getDocNo,docNo));
        smsCheckDocRecordService.remove(new LambdaQueryWrapper<SmsCheckDocRecord>().eq(SmsCheckDocRecord::getDocNo,docNo));
        List<SmsCheckDocDetail> smsCheckDocDetails = smsCheckDocDTO.getSmsCheckDocDetails();
        if (smsCheckDocDetails == null||smsCheckDocDetails.isEmpty()) {
            return Result.failed(  "详情列表不能为空");
        }
        smsCheckDocDetails.forEach(u->{
            u.setDocNo(docNo);
        });
        saveOrUpdate(smsCheckDoc);
        smsCheckDocDetailService.saveBatch(smsCheckDocDetails);

        Integer checkStockState = smsCheckDoc.getCheckStockState();
        List<SmsCheckDocRecord> smsReturnDocRecords = new ArrayList<>();
        for (SmsCheckDocDetail smsCheckDocDetail : smsCheckDocDetails) {
            String itemCode = smsCheckDocDetail.getItemCode();
            List<SmsStockInfo> stockInfos =new ArrayList<>();
            if (checkStockState==0){
                stockInfos=smsStockInfoService.list(new LambdaQueryWrapper<SmsStockInfo>()
                        .eq(SmsStockInfo::getItemCode,itemCode)
                        .eq(SmsStockInfo::getWarehouse, CheckWarehouseEnum.S_3.getWarehouse())
                );
            }else {
                stockInfos=smsStockInfoService.list(new LambdaQueryWrapper<SmsStockInfo>()
                        .eq(SmsStockInfo::getItemCode,itemCode)
                        .eq(SmsStockInfo::getWarehouse, CheckWarehouseEnum.S_3.getWarehouse())
                        .eq(SmsStockInfo::getStockState,checkStockState)
                );
            }
            for (SmsStockInfo stockInfo : stockInfos) {
                SmsCheckDocRecord smsCheckDocRecord = new SmsCheckDocRecord();
                smsCheckDocRecord.setDocNo(docNo);
                smsCheckDocRecord.setDdId(smsCheckDocDetail.getId());
                smsCheckDocRecord.setSn(stockInfo.getSn());
                smsCheckDocRecord.setAreaSn(stockInfo.getAreaSn());
                smsCheckDocRecord.setQty(stockInfo.getQty());
                smsCheckDocRecord.setState(1);
                smsCheckDocRecord.setCreateName(smsCheckDoc.getDocName());
                smsReturnDocRecords.add(smsCheckDocRecord);
            }
        }
        smsCheckDocRecordService.saveBatch(smsReturnDocRecords);
        return Result.succeed("保存成功");
    }

    @Override
    public Result close(SmsCheckDoc smsCheckDoc) {
        String docNo = smsCheckDoc.getDocNo();
        SmsCheckDoc checkDoc = getOne(new LambdaQueryWrapper<SmsCheckDoc>().eq(SmsCheckDoc::getDocNo, docNo));
        checkDoc.setDocState(3);
        updateById(checkDoc);
        return Result.succeed("保存成功");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result scanSN(Map<String, Object> map) {
        try{
            log.info("扫码盘点请求参数{}",map);
            String sn = MapUtil.getStr(map, "sn");
            String createName = MapUtil.getStr(map, "createName");
            String docNo = MapUtil.getStr(map, "docNo");
            Integer docType = MapUtil.getInt(map, "docType");

            SmsCheckDoc checkDoc = getOne(new LambdaQueryWrapper<SmsCheckDoc>().eq(SmsCheckDoc::getDocNo, docNo));
            if (checkDoc == null) {
                return Result.failed("无此单号");
            }
/*            if (!checkDoc.getDocType().equals(docType)){
                return Result.failed("类型不符");
            }*/
            SmsCheckDocRecord record = smsCheckDocRecordService.getOne(new LambdaQueryWrapper<SmsCheckDocRecord>()
                    .eq(SmsCheckDocRecord::getDocNo, docNo)
                    .eq(SmsCheckDocRecord::getSn, sn)
                    .eq(SmsCheckDocRecord::getState, 1)
            );
            if (record == null) {
                return Result.failed("条码与单号不符");
            }
            SmsStockInfo stockInfo = smsStockInfoService.getOne(new LambdaQueryWrapper<SmsStockInfo>().eq(SmsStockInfo::getSn, sn));
            if (stockInfo == null) {
                return Result.failed("无此库存");
            }
            if(stockInfo.getStockState()!=1){
                return Result.failed("条码非在库状态");
            }

            //修改备料状态
            record.setState(2);
            record.setCreateName(createName);
            smsCheckDocRecordService.updateById(record);

            //修改详情的数量
            Long ddId = record.getDdId();
            SmsCheckDocDetail docDetail = smsCheckDocDetailService.getById(ddId);
            docDetail.setCheckEndQty(docDetail.getCheckEndQty()+stockInfo.getQty());
            smsCheckDocDetailService.updateById(docDetail);

            //修改盘点单状态
            int totalCount = smsCheckDocRecordService.count(new LambdaQueryWrapper<SmsCheckDocRecord>().eq(SmsCheckDocRecord::getDocNo, docNo));
            int hasCheckCount = smsCheckDocRecordService.count(new LambdaQueryWrapper<SmsCheckDocRecord>().eq(SmsCheckDocRecord::getDocNo, docNo).eq(SmsCheckDocRecord::getState, 2));
            checkDoc.setDocState(2);
            checkDoc.setState(totalCount==hasCheckCount?3:2);
            updateById(checkDoc);

            return Result.succeed("保存成功");
        }
        catch (Exception e){
            // 事务回滚
            log.error("扫码盘点异常：",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.failed( e,"保存失败，请联系管理员");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result delete(Map<String, List<Long>> map) {
        try{
            List<Long> ids = map.get("ids");
            for (Long id : ids) {
                SmsCheckDoc smsCheckDoc = getById(id);
                if (smsCheckDoc.getDocState()!=1){
                    int i=1/0;
                }
                String docNo = smsCheckDoc.getDocNo();
                removeById(id);
                smsCheckDocDetailService.remove(new LambdaQueryWrapper<SmsCheckDocDetail>()
                        .eq(SmsCheckDocDetail::getDocNo,docNo)
                );
            }
            return Result.succeed("删除成功");
        }
        catch (Exception e){
            // 事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.failed( e,"保存失败，单状态非新建");
        }
    }


    /**
     * 获取新的串号
     * @return 当前串号的下一个串号
     */
    private String getNewNo(){
        //生成新的串号
        String prefix="CH" + DateUtil.format(new Date(), "yyyyMMdd");
        String maxNo=prefix+"001";
        SmsCheckDoc one = getOne(new QueryWrapper<SmsCheckDoc>()
                .last("where doc_no like '" + prefix + "%' order by doc_no desc limit 1"));
        if (one != null) {
            Long aLong = Convert.toLong(StrUtil.removePrefix(one.getDocNo(), prefix));
            maxNo=prefix+String.format("%3d",aLong+1).replace(" ","0");
        }
        return maxNo;
    }
}
